package com.ruoyi.quartz.task;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SensorParameters;
import com.ruoyi.system.service.ISensorParametersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * Tcp定时任务
 *
 * @author
 */
@Component("tcpTask")
public class TcpTask {

    @Autowired
    private ISensorParametersService sensorParametersService;
    private static ServerSocket serverSocket;

    private static Socket clientSocket;

    private static DataOutputStream dos;

    private static InputStream ips;
    private static OutputStream ops;

    private static int j;

    public void TcpServer() {
        try {
//            String[] sites = {"01","02","03"};
            String[] sites = {"01"};
            serverSocket = new ServerSocket(14000);
            System.out.println("Waiting for clients on port: " + 14000);

            clientSocket = serverSocket.accept(); // 接受客户端连接
            System.out.println("Client connected: " + clientSocket.getRemoteSocketAddress());
            Thread.sleep(2000);
            dos = new DataOutputStream(clientSocket.getOutputStream());

            ips = clientSocket.getInputStream();     // 有client连上来，打开输入流
            ops = clientSocket.getOutputStream();   // 打开输出流
            // 同一个通道，服务端的输出流就是客户端的输入流；服务端的输入流就是客户端的输出流
            for (String site : sites) {
                j = 0;
                //读取温度值
                String wd = "03 00 30 00 02 C4 04";
//                if (site.equals("02")){
//                    wd = "03 15 4A 00 02 E1 E2";
//                }else if (site.equals("03")){
//                    wd = "03 15 4A 00 02 E0 33";
//                }
                String hexString = site + " " + wd; // 需要发送的16进制字符串
                BigDecimal temperature = sendAndReceive(site, hexString);
                System.out.println(site + "--温度值：" + temperature);
                //读取电导率
                String ddl = "03 00 38 00 02 45 C6";
//                if (site.equals("02")){
//                    ddl = "03 15 82 00 02 60 1C";
//                }else if (site.equals("03")){
//                    ddl = "03 15 82 00 02 61 CD";
//                }
                hexString = site + " " + ddl; // 需要发送的16进制字符串
                BigDecimal conductivity = sendAndReceive(site, hexString);
                System.out.println(site + "--电导率值：" + conductivity);
                //读取比电导率
//                String bddl = "03 15 89 00 02 11 ED";
//                if (site.equals("02")){
//                    bddl = "03 15 89 00 02 11 DE";
//                }else if (site.equals("03")){
//                    bddl = "03 15 89 00 02 10 0F";
//                }
//                hexString = site + " " + bddl; // 需要发送的16进制字符串
//                BigDecimal specificConductivity = sendAndReceive(site,hexString);
//                System.out.println(site + "--比电导率值：" + specificConductivity);
                //读取盐度
                String yd = "03 00 58 00 02 45 D8";
//                if (site.equals("02")){
//                    yd = "03 15 97 00 02 71 D8";
//                }else if (site.equals("03")){
//                    yd = "03 15 97 00 02 70 09";
//                }
                hexString = site + " " + yd; // 需要发送的16进制字符串
                BigDecimal salinity = sendAndReceive(site, hexString);
                System.out.println(site + "--盐度值：" + salinity);
                //读取tds
//                String rjxgt = "03 15 9E 00 02 A1 E9";
//                if (site.equals("02")){
//                    rjxgt = "03 15 9E 00 02 A1 DA";
//                }else if (site.equals("03")){
//                    rjxgt = "03 15 9E 00 02 A0 0B";
//                }
//                hexString = site + " " + rjxgt; // 需要发送的16进制字符串
//                BigDecimal tds = sendAndReceive(site,hexString);
//                System.out.println(site + "--TDS值：" + tds);
                //读取PH
                String sjd = "03 00 4A 00 02 E5 DD";
//                if (site.equals("02")){
//                    sjd = "03 15 BA 00 02 E1 D1";
//                }else if (site.equals("03")){
//                    sjd = "03 15 BA 00 02 E0 00";
//                }
                hexString = site + " " + sjd; // 需要发送的16进制字符串
                BigDecimal ph = sendAndReceive(site, hexString);
                System.out.println(site + "--PH值：" + ph);
                //读取ORP
//                String orpz = "03 15 C8 00 02 41 F9";
//                if (site.equals("02")){
//                    orpz = "03 15 C8 00 02 41 CA";
//                }else if (site.equals("03")){
//                    orpz = "03 15 C8 00 02 40 1B";
//                }
//                hexString = site + " " + orpz; // 需要发送的16进制字符串
//                BigDecimal orp = sendAndReceive(site,hexString);
//                System.out.println(site + "--ORP值：" + orp);
                //读取浊度值
                String zhudu = "03 00 36 00 02 24 05";
//                if (site.equals("02")){
//                    zhudu = "03 15 F2 00 02 61 C7";
//                }else if (site.equals("03")){
//                    zhudu = "03 15 F2 00 02 60 16";
//                }
                hexString = site + " " + zhudu; // 需要发送的16进制字符串
                BigDecimal turbidity = sendAndReceive(site, hexString);
                System.out.println(site + "--浊度值：" + turbidity);
                //读取叶绿素值
                String yls = "03 00 3A 00 02 E4 06";
//                if (site.equals("02")){
//                    yls = "03 16 A8 00 02 41 90";
//                }else if (site.equals("03")){
//                    yls = "03 16 A8 00 02 40 41";
//                }
                hexString = site + " " + yls; // 需要发送的16进制字符串
                BigDecimal chl = sendAndReceive(site, hexString);
                System.out.println(site + "--叶绿素值：" + chl);
                //读取溶解氧
                String rjy = "03 00 32 00 02 65 C4";
                hexString = site + " " + rjy; // 需要发送的16进制字符串
                BigDecimal dissolvedOxygen = sendAndReceive(site, hexString);
                System.out.println("溶解氧浓度值：" + dissolvedOxygen);
//                //读取深度
                String sd = "03 00 5E 00 02 A5 D9";
                hexString = site + " " + sd; // 需要发送的16进制字符串
                BigDecimal depth = sendAndReceive(site, hexString);
                System.out.println("深度值：" + depth);
                //读取cod
                String codz = "03 00 32 00 02 65 C4";
                hexString = site + " " + codz; // 需要发送的16进制字符串
                BigDecimal cod = sendAndReceive(site, hexString);
                System.out.println("cod值：" + cod);
                //读取气象温度
                String qxwd = "66 03 00 00 00 01 8C 1D";
                BigDecimal meteorologicalTemperature = sendAndReceive(site, qxwd);
                System.out.println("气象温度值：" + meteorologicalTemperature);
                //读取气象湿度
                String qxsd = "66 03 00 01 00 01 DD DD";
                BigDecimal meteorologicalHumidity = sendAndReceive(site, qxsd);
                System.out.println("气象湿度值：" + meteorologicalHumidity);
                //读取气象压力
                String qxyl = "66 03 00 02 00 01 2D DD";
                BigDecimal meteorologicalPressure = sendAndReceive(site, qxyl);
                System.out.println("气象压力值：" + meteorologicalPressure);
                //读取水压力
//                String syl = "01 03 00 60 00 02 C4 15";
//                BigDecimal pressure = sendAndReceive(site, syl);
//                BigDecimal subtract = pressure.subtract(meteorologicalPressure);
//                System.out.println("水压力：" + subtract);
                //读取气象风速
                String qxfs = "C8 03 00 00 00 01 95 93";
                BigDecimal meteorologicalWindSpeed = sendAndReceive(site, qxfs);
                System.out.println("气象风速值：" + meteorologicalWindSpeed);
                //读取气象风向
                String qxfx = "C8 03 00 01 00 01 C4 53";
                BigDecimal meteorologicalWindDirection = sendAndReceive(site, qxfx);
                System.out.println("气象风向值：" + meteorologicalWindDirection);

                //A，读取0x5E（水深：米）值X1 和外置（第三方）气压传感器X2（单位kPa）
                //B，计算水深D=X1-（X2-101.31）*0.1019726, 计算结果单位：米。
                BigDecimal qy = meteorologicalPressure.subtract(new BigDecimal(101.31));
                qy = qy.multiply(new BigDecimal(0.1019726));
                BigDecimal dep = depth.subtract(qy);
                dep = dep.setScale(2, RoundingMode.HALF_UP);

                SensorParameters sensorParameters = new SensorParameters();
                sensorParameters.setTemperature(temperature);
//                sensorParameters.setPressure(subtract);
                sensorParameters.setConductivity(conductivity);
//                sensorParameters.setSpecificConductivity(specificConductivity);
                sensorParameters.setSalinity(salinity);
//                sensorParameters.setTds(tds);
                sensorParameters.setPh(ph);
//                sensorParameters.setOrp(orp);
                sensorParameters.setTurbidity(turbidity);
                sensorParameters.setChl(chl);
                sensorParameters.setDissolvedOxygen(dissolvedOxygen);
                sensorParameters.setCod(cod);
                sensorParameters.setDepth(dep);
                sensorParameters.setMeteorologicalTemperature(meteorologicalTemperature);
                sensorParameters.setMeteorologicalHumidity(meteorologicalHumidity);
                sensorParameters.setMeteorologicalPressure(meteorologicalPressure);
                sensorParameters.setMeteorologicalWindSpeed(meteorologicalWindSpeed);
                sensorParameters.setMeteorologicalWindDirection(meteorologicalWindDirection);
                sensorParameters.setSite(site);
                sensorParameters.setCreateTime(new Date());
                sensorParameters.setStatus("1");
                sensorParametersService.updateSensorParametersStatus();
                sensorParametersService.insertSensorParameters(sensorParameters);
            }
            dos.close();
            ips.close();
            ops.close();
            clientSocket.close();
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static byte[] hexStrToBinaryStr(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }
        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;
        byte[] bytes = new byte[len / 2];
        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
            index += 2;
        }
        return bytes;
    }

    public static String BinaryToHexString(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        String result = "";
        String hex = "";
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result += hex + " ";
        }
        return result;
    }

    public static BigDecimal hexStringToBigDecimal(String hex) {
        String hexString = "";
        hex = hex.substring(9, 20);
        String[] values = hex.split(" ");        // 使用空格作为分隔符分割字符串
        for (int i = values.length - 1; i >= 0; i--) { // 倒序遍历数组
            if (i != 0) {
                hexString += values[i] + " "; // 打印值后跟一个空格
            } else {
                hexString += values[i];    // 打印最后一个值后换行
            }
        }
        hex = hexString.replaceAll(" ", "");
        System.out.println("返回字节：" + hex);
        int intBits = Integer.parseInt(hex, 16);
        float floatValue = Float.intBitsToFloat(intBits);
        BigDecimal bd = BigDecimal.valueOf(floatValue);
        // 设置舍入模式为四舍五入，并保留两位小数
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println("转换后：" + bd);
        return bd;
    }

    public static BigDecimal hexStringToDepBigDecimal(String hex) {
        String hexString = "";
        hex = hex.substring(9, 20);
        String[] values = hex.split(" ");        // 使用空格作为分隔符分割字符串
        for (int i = values.length - 1; i >= 0; i--) { // 倒序遍历数组
            if (i != 0) {
                hexString += values[i] + " "; // 打印值后跟一个空格
            } else {
                hexString += values[i];    // 打印最后一个值后换行
            }
        }
        hex = hexString.replaceAll(" ", "");
        System.out.println("返回字节：" + hex);
        int intBits = Integer.parseInt(hex, 16);
        float floatValue = Float.intBitsToFloat(intBits);
        BigDecimal bd = BigDecimal.valueOf(floatValue);

        // 设置舍入模式为四舍五入，并保留两位小数
//        bd = bd.setScale(2, RoundingMode.HALF_UP);
//        System.out.println("转换后："+bd);
        return bd;
    }

    public static void main(String[] args) {
        String s = "01 03 04 FE DD CC 42 8E D0";
        BigDecimal bigDecimal = hexStringToBigDecimalQx(s);
    }

    public static BigDecimal hexStringToBigDecimalQx(String hex) {
        String hexString = "";
        hex = hex.substring(9, 14);
        hex = hex.replaceAll(" ", "");
        System.out.println("返回字节：" + hex);
        int intBits = Integer.parseInt(hex, 16);
        BigDecimal bd = BigDecimal.valueOf(intBits).divide(new BigDecimal(100));
        // 设置舍入模式为四舍五入，并保留两位小数
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println("转换后：" + bd);
        return bd;
    }

    public static BigDecimal hexStringToBigDecimalQxwd(String hex) {
        String hexString = "";
        hex = hex.substring(9, 14);
        String[] values = hex.split(" ");        // 使用空格作为分隔符分割字符串

//        hex = hexString.replaceAll(" ","");
        System.out.println("返回字节：" + hex);
        int h = Integer.parseInt(values[0], 16);
        int l = Integer.parseInt(values[1], 16);
        int b = h * 256 + l;
        if (b > 32768) {
            b = b - 65536;
        }
        BigDecimal bd = BigDecimal.valueOf(b).divide(new BigDecimal(100));
        // 设置舍入模式为四舍五入，并保留两位小数
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println("转换后：" + bd);
        return bd;
    }

    public static BigDecimal hexStringToBigDecimalQxfs(String hex) {
        String hexString = "";
        hex = hex.substring(9, 14);
        String[] values = hex.split(" ");        // 使用空格作为分隔符分割字符串

//        hex = hexString.replaceAll(" ","");
        System.out.println("返回字节：" + hex);
        int h = Integer.parseInt(values[0], 16);
        int l = Integer.parseInt(values[1], 16);
        int b = h * 256 + l;
//        if ( b > 32768 ){
//            b = b - 65536;
//        }
        BigDecimal bd = BigDecimal.valueOf(b).divide(new BigDecimal(100));
        // 设置舍入模式为四舍五入，并保留两位小数
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println("转换后：" + bd);
        return bd;
    }

    public static BigDecimal hexStringToBigDecimalQxfx(String hex) {
        String hexString = "";
        hex = hex.substring(9, 14);
        hex = hex.replaceAll(" ", "");
        System.out.println("返回字节：" + hex);
        int intBits = Integer.parseInt(hex, 16);
        BigDecimal bd = BigDecimal.valueOf(intBits);
        // 设置舍入模式为四舍五入，并保留两位小数
        bd = bd.setScale(2, RoundingMode.HALF_UP);
        System.out.println("转换后：" + bd);
        return bd;
    }

    public static BigDecimal sendAndReceive(String site, String hexString) {
        BigDecimal num = new BigDecimal(0);
        try {
            boolean flag = true;
            System.out.println("发送的数据：" + hexString);
            byte[] bytes = hexStrToBinaryStr(hexString);
            dos.write(bytes);
            dos.flush();
            //输出两次
//            for (int i = j; i < 2; i++) {
//                // 等待一段时间，然后再次发送
            Thread.sleep(1000);
//                j++;
//                System.out.println("发送的数据：" + hexString);
//                bytes = hexStrToBinaryStr(hexString);
//                // 假设我们正在读取寄存器，从地址0开始，读取1个寄存器
//                dos.write(bytes);
//                dos.flush();
//
//            }
            // 接收数据
            //获取输入流，读数据，并把数据显示到控制台
            InputStream is = clientSocket.getInputStream();
//            byte[] bys = new byte[1024];
//            int len = is.read(bys);
//            bys = Arrays.copyOfRange(bys,0,len);
//            String data = BinaryToHexString(bys);
//            System.out.println("返回数据是：" + data);
            while (flag) {
                //接收服务器的响应
                int line = 0;
//                int available = is.available();
//                if(available==0){
//                    continue;
//                }
                byte[] buf = new byte[9];
                //接收收到的数据
                String strReturn = "";
                while ((line = is.read(buf)) != -1) {
                    //将字节数组转换成十六进制的字符串
                    strReturn = BinaryToHexString(buf);
                    if (!strReturn.isEmpty()) {
                        String str = strReturn.replaceAll(" ", "");
                        str = str.substring(0, 8);
                        String restr = str.substring(0, 6);
                        String shuju = site + "0304";
                        String hex = hexString.replaceAll(" ", "");
                        if (str.equals("AAFF1122") || str.equals("AAFF3322") || str.equals("AAFF2222")) {
                            System.out.println("心跳");
                            if (!flag) {
                                break;
                            }
                        } else if (restr.equals(shuju)) {
                            if (hex.contains("03005E")) {
                                //查的是深度
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToDepBigDecimal(strReturn);
                                flag = false;
                                break;
                            } else {
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimal(strReturn);
                                flag = false;
                                break;
                            }
                        } else {
                            //03 00 30 00 02 C4 04
                            //读取电导率
//                            String ddl = "03 00 38 00 02 45 C6";
                            //读取盐度
//                            String yd = "03 00 58 00 02 45 D8";
//                            //读取PH
//                            String sjd = "03 00 4A 00 02 E5 DD";
//                            //读取浊度值
//                            String zhudu = "03 00 36 00 02 24 05";
//                            //读取叶绿素值
//                            String yls = "03 00 3A 00 02 E4 06";
//                            //读取溶解氧
//                            String rjy = "03 00 32 00 02 65 C4";
////                //读取深度
//                            String sd = "03 00 5E 00 02 A5 D9";
//                            //读取cod
//                            String codz = "03 00 32 00 02 65 C4";
                            if (hex.equals("6603000000018C1D")) {
                                //气象温度
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimalQxwd(strReturn);
                                flag = false;
                                break;
                            } else if (hex.equals("660300010001DDDD")) {
                                //气象湿度
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimalQx(strReturn);
                                flag = false;
                                break;
                            } else if (hex.equals("6603000200012DDD")) {
                                //气象压力
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimalQx(strReturn);
                                flag = false;
                                break;
                            } else if (hex.equals("C803000000019593")) {
                                //气象风速
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimalQxfs(strReturn);
                                flag = false;
                                break;
                            } else if (hex.equals("C80300010001C453")) {
                                //气象风向
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimalQxfx(strReturn);
                                flag = false;
                                break;
                            }else if(hex.equals("010300600002C415")){
                                //水压？？？？？？？？？
                                System.out.println("返回数据是：" + strReturn);
                                num = hexStringToBigDecimal(strReturn);
                                flag = false;
                                break;
                            }
                        }
                    }
                }
            }
//            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
//            byte[] dataBuffer = new byte[1024];
//            int bytesRead;
//            while ((bytesRead = ips.read(dataBuffer)) != -1) {
//                buffer.write(dataBuffer, 0, bytesRead);
//            }
//            byte[] data = buffer.toByteArray();
//            System.out.println("接收到的数据：");
//            if (data.length > 0) {
//                String res = BinaryToHexString(data);
//                System.out.print(res);
//                BigDecimal bd = hexStringToBigDecimal(res);
//                return bd;
//            }
//            return new BigDecimal(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return num;
    }
}
